# This file is part of the Net::Tube module.
#
# Net::Tube is Free Software; you can use, redistribute it and/or
# modify it under the terms of either:
#
# a) the GNU General Public License as published by the Free Software
#    Foundation, either version 2, or (at your opinion) any later
#    version, or
#
# b) the "Artistic License" which comes with Perl.
#

package Net::Tube::Loader::Net;

use Net::Tube::Loader;
use LWP::UserAgent;
use Digest::MD5 qw(md5_hex);

our $VERSION   = "0.01";
our $USERAGENT = "Net::Tube Net Loader/$VERSION";

our @ISA = qw(Net::Tube::Loader);

sub user_agent {
    my $self = shift;
    unless ( defined $self->{_USERAGENT} ) {
        $self->{_USERAGENT} = LWP::UserAgent->new( agent => $USERAGENT );
    }
    return $self->{_USERAGENT};
}

sub clean_url {
    my $self = shift;
    my $url  = shift;
    return ( defined $url && ref $url && $url->isa("XML::LibXML::Node") )
      ? $url->textContent()
      : $url;
}

sub get_data {
    my $self = shift;
    my $url  = $self->clean_url( shift @_ );

    my ($cache) = $self->get_config_entry('use-cache');

    unless ( defined $cache ) {
        $cache = 'yes';
    }

    if ( defined $url && length $url ) {
        my $data;
        if ( $cache eq 'yes' ) {
            $data = $self->check_cache($url);
	}
        unless ( defined $data && length $data ) {
            my $agent = $self->user_agent;
            my $res   = $agent->get($url);
            if ( defined $res ) {
                if ( $res->code == 200 ) {
                    # cache the data
                    $data = $res->decoded_content();
                    my $ocache = $self->cache_object();
                    if ( defined $ocache ) {
                        # warn "store data to cache";
                        $ocache->set( $url, $data );
                        # warn "stored data to cache";
                    }
                }
                elsif ( $res->code == 304 ) {

                    # the server asks us to use a cached version

                }
            }
        }
        return $data;
    }
    return undef;
}

##
# post_data(@url, @envelope)
sub post_data {
    my $self = shift;
    my $url  = $self->clean_url( shift @_ );
    my $env  = shift;
    my $data;
    my $a = $self->user_agent;

    if ( defined $url && length $url ) {
        my $res;

        if ( defined $env ) {
            if ( ref $env ) {
                $res = $a->post( $url, $env );
            }
            elsif ( length $env ) {
                $res = $a->post( $url, Content => $env );
            }
        }

        # in those cases where there is no envelope, we simply get the URL
        unless ( defined $res ) {
            $res = $a->get($url);
        }
        if ( defined $res && $res->code == 200 ) {
            $data = $res->decoded_content();
        }
    }
    return $data;
}

# cached_post_data is a helper function to enable cache for
# requests that need to send request parameters via HTTP-POST
sub cached_post_data {
    my $self = shift;
    my $url  = $self->clean_url( shift @_ );
    my $env  = shift;

    my $data;
    if ( defined $url && length $url ) {
        if ( defined $env && ( ref $env || length $env ) ) {
            $data = $self->check_cache( $url, $env );
            unless ( defined $data ) {
                my $a = $self->user_agent;
                my $res;

                if ( ref $env ) {
                    $res = $a->post( $url, $env );
                }
                elsif ( length $env ) {
                    $res = $a->post( $url, Content => $env );
                }
                if ( defined $res && $res->code == 200 ) {
                    $data = $res->decoded_content();    # cache the data, too
                }
            }
        }
        else {
            $data = $self->get_data($url);
        }
    }
    return $data;
}

##
# fetch_to_bucket(@bucket, @url)
# @bucket: reference to bucket class
# @url: URL to fetch.
# This function retrieves XML or JSON data from the given URL.
sub fetch_to_bucket {
    my $self   = shift;
    my $bucket = shift;
    my $url    = shift;

    my $data = $self->get_data($url);
    $self->add_to_bucket( $bucket, $data, $url );
}

# default load function is good for fetching RSS and Atom Feeds
sub load {
    my $self = shift;
    $self->fetch_to_bucket(@_);
}

sub check_cache {
    my $self = shift;
    my $url  = shift;
    my @args = @_;

    my $ocache = $self->cache_object();
    if ( defined $ocache ) {
        # warn "check cache";
        my $key = $url;
        if ( scalar @args ) {
            $key .= md5_hex(@args);
        }
        # warn $key;
        my $data;
        eval {    
            $data = $ocache->get($key);
        };
        if ( defined $data && length $data ) {
            return $data;
        }
        # warn "no information in cache";
    }

    return undef;
}

1;
